<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
/**
 *  tests for create binary tree
 * 
 * @package    questions
 * @category   Calculate Expression
 * @copyright  2014 Quoc Dai
 * @author	   Quoc Dai, Volgograd State Technical University
 * @license    http://www.gnu.org/copyleft/gpl.html GNU Public License
 */
global $CFG;
require_once($CFG->dirroot.'/question/type/cppexpression/qtype_cppexpression_create_tree.php');

/**
 * Optimizes tree replacing nodes with one child with their child
 * @param array|block_formal_langs_processed_string $nodes nodes
 * @return array optimized array of trees
 */

class qtype_cppexpression_create_binary_tree_test extends PHPUnit_Framework_TestCase{
	
	/**
	 * compare two nodes of two binary trees
	 * @param node|qtype_cppexpression_binary_tree $node1
	 * @param node|qtype_cppexpression_binary_tree $node2
	 * @return true or false
	 */
	static function compare_nodes($node1, $node2){
		
		$equal = $node1->get_type_nodes() == $node2->get_type_nodes();
		$equal &= $node1->pos == $node2->pos;
		
		if ( $equal && $node1->get_type_nodes() == 'PARAMETER') {
			$equal &= $node1->type == $node2->type;

			if ($equal && $node1->type = 'NUMBER') {
				$equal &= $node1->data == $node2->data;
			}
		}

		return $equal;
	}


	/**
	 * compare two binary trees
	 * @param node|qtype_cppexpression_binary_tree $tree1
	 * @param node|qtype_cppexpression_binary_tree $tree2
	 * @param boolean $equal
	 * @return true or false
	 */
	static function compare_trees($tree1, $tree2){
		
		$equal = true;

		if (($tree1 && !$tree2) || ( !$tree1 && $tree2)) {
			return false;
		}

		if (!$tree1 && !$tree2) {
			return true;
		}

		$equal = $equal && self::compare_nodes($tree1, $tree2);

		if (!$equal) {
			return $equal;
		}

		$equal = $equal && self::compare_trees($tree1->childLeft, $tree2->childLeft);
		$equal = $equal && self::compare_trees($tree1->childRight,$tree2->childRight);

		return $equal;
	}



/*---------------------------------------------tests for function qtype_cppexpression_create_tree::create_tree--------------------------------------------*/

	public function test_empty(){
		$binaryTree = new qtype_cppexpression_create_tree('');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree == NULL);
	}


	public function test_create_node_parameter(){
		$binaryTree = new qtype_cppexpression_create_tree('i');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('i', 0);

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_plus(){
		$binaryTree = new qtype_cppexpression_create_tree('i + 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('+', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_sub(){
		$binaryTree = new qtype_cppexpression_create_tree('i - 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('-', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_mul(){
		$binaryTree = new qtype_cppexpression_create_tree('i * 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('*', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_div(){
		$binaryTree = new qtype_cppexpression_create_tree('i / 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('/', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_percent(){
		$binaryTree = new qtype_cppexpression_create_tree('i % 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('%', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_greater(){
		$binaryTree = new qtype_cppexpression_create_tree('i > 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('>', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_less(){
		$binaryTree = new qtype_cppexpression_create_tree('i < 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('<', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_greater_or_equal(){
		$binaryTree = new qtype_cppexpression_create_tree('i >= 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('>=', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_less_or_equal(){
		$binaryTree = new qtype_cppexpression_create_tree('i <= 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('<=', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_equal(){
		$binaryTree = new qtype_cppexpression_create_tree('i == 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('==', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_different(){
		$binaryTree = new qtype_cppexpression_create_tree('i != 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('!=', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_and(){
		$binaryTree = new qtype_cppexpression_create_tree('i && 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('&&', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_or(){
		$binaryTree = new qtype_cppexpression_create_tree('i || 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('||', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_not(){
		$binaryTree = new qtype_cppexpression_create_tree('! i');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('!', 0);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 1);
		$resultTree->childLeft->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	/*public function test_create_node_or_bit(){
		$binaryTree = new qtype_cppexpression_create_tree('i | 1');
		$tree = $binaryTree->get_binary_tree();

		/*echo "\n\n";
		var_dump($tree);
		echo "\n\n";

		$resultTree = qtype_cppexpression_create_tree::create_node('|', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('1', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_and_bit(){
		$binaryTree = new qtype_cppexpression_create_tree('i & 5');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('&', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('5', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}*/


	public function test_create_node_not_bit(){
		$binaryTree = new qtype_cppexpression_create_tree('~ i');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('~', 0);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 1);
		$resultTree->childLeft->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_xor_bit(){
		$binaryTree = new qtype_cppexpression_create_tree('i ^ 1');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('^', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('1', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_leftShift(){
		$binaryTree = new qtype_cppexpression_create_tree('i << 1');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('<<', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('1', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_node_rightShift(){
		$binaryTree = new qtype_cppexpression_create_tree('i >> 1');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('>>', 1);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('1', 2);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_tree_from_string_has_one_bracket_1(){
		$binaryTree = new qtype_cppexpression_create_tree('(i + 1)');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('+', 2);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('i', 1);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('1', 3);
		$resultTree->childRight->parent = $resultTree;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_tree_from_string_has_one_bracket_2(){
		$binaryTree = new qtype_cppexpression_create_tree('!(i + 1)');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('!', 0);
		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('+', 3);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childLeft->childLeft = qtype_cppexpression_create_tree::create_node('i', 2);
		$resultTree->childLeft->childLeft->parent = $resultTree->childLeft;

		$resultTree->childLeft->childRight = qtype_cppexpression_create_tree::create_node('1', 4);
		$resultTree->childLeft->childRight->parent = $resultTree->childLeft;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_tree_from_string_has_one_bracket_3(){
		$binaryTree = new qtype_cppexpression_create_tree('(i + 1) > j');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('>', 5);
		
		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('+', 2);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('j', 6);
		$resultTree->childRight->parent = $resultTree;

		$resultTree->childLeft->childLeft = qtype_cppexpression_create_tree::create_node('i', 1);
		$resultTree->childLeft->childLeft->parent = $resultTree->childLeft;

		$resultTree->childLeft->childRight = qtype_cppexpression_create_tree::create_node('1', 3);
		$resultTree->childLeft->childRight->parent = $resultTree->childLeft;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_tree_from_string_has_two_brackets(){
		$binaryTree = new qtype_cppexpression_create_tree('(i + 1) > (j * 2)');
		$tree = $binaryTree->get_binary_tree();

		$resultTree = qtype_cppexpression_create_tree::create_node('>', 5);
		
		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('+', 2);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childLeft->childLeft = qtype_cppexpression_create_tree::create_node('i', 1);
		$resultTree->childLeft->childLeft->parent = $resultTree->childLeft;

		$resultTree->childLeft->childRight = qtype_cppexpression_create_tree::create_node('1', 3);
		$resultTree->childLeft->childRight->parent = $resultTree->childLeft;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('*', 8);
		$resultTree->childRight->parent = $resultTree;

		$resultTree->childRight->childLeft = qtype_cppexpression_create_tree::create_node('j', 7);
		$resultTree->childRight->childLeft->parent = $resultTree->childRight;

		$resultTree->childRight->childRight = qtype_cppexpression_create_tree::create_node('2', 9);
		$resultTree->childRight->childRight->parent = $resultTree->childRight;

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


	public function test_create_tree_from_complex_expression(){
		$binaryTree = new qtype_cppexpression_create_tree('!(i + 1) && (9 > (j - 3))');
		$tree = $binaryTree->get_binary_tree();

		/*echo "\n\n\n\n\t\t\t\t\t\t--------------------------------------------\n\n";

		var_dump($tree);*/

		$resultTree = qtype_cppexpression_create_tree::create_node('&&', 6);

		$resultTree->childLeft = qtype_cppexpression_create_tree::create_node('!', 0);
		$resultTree->childLeft->parent = $resultTree;

		$resultTree->childLeft->childLeft = qtype_cppexpression_create_tree::create_node('+', 3);
		$resultTree->childLeft->childLeft->parent = $resultTree->childLeft;

		$resultTree->childLeft->childLeft->childLeft = qtype_cppexpression_create_tree::create_node('i', 2);
		$resultTree->childLeft->childLeft->childLeft->parent = $resultTree->childLeft->childLeft;

		$resultTree->childLeft->childLeft->childRight = qtype_cppexpression_create_tree::create_node('1', 4);
		$resultTree->childLeft->childLeft->childRight->parent = $resultTree->childLeft->childLeft;

		$resultTree->childRight = qtype_cppexpression_create_tree::create_node('>', 9);
		$resultTree->childRight->parent = $resultTree;

		$resultTree->childRight->childLeft = qtype_cppexpression_create_tree::create_node('9', 8);
		$resultTree->childRight->childLeft->parent = $resultTree->childRight;

		$resultTree->childRight->childRight = qtype_cppexpression_create_tree::create_node('-', 12);
		$resultTree->childRight->childRight->parent = $resultTree->childRight;

		$resultTree->childRight->childRight->childLeft = qtype_cppexpression_create_tree::create_node('j', 11);
		$resultTree->childRight->childRight->childLeft->parent = $resultTree->childRight->childRight;

		$resultTree->childRight->childRight->childRight = qtype_cppexpression_create_tree::create_node('3', 13);
		$resultTree->childRight->childRight->childRight->parent = $resultTree->childRight->childRight;

		/*echo "\n\n\n\n\t\t\t\t\t\t--------------------------------------------\n\n";

		var_dump($resultTree);

		echo "\n\n\n\n\t\t\t\t\t\t--------------------------------------------\n\n";*/

		$this->assertTrue(self::compare_trees($tree, $resultTree));
	}


/*---------------------------------tests for function qtype_cppexpression_binary_tree::calculate_expression-----------------------------*/


	public function test_plus(){
		$binaryTree = new qtype_cppexpression_create_tree('i + j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(2, 3) == 5);
	}


	public function test_sub(){
		$binaryTree = new qtype_cppexpression_create_tree('i - j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(2, 3) == -1);
	}


	public function test_mul(){
		$binaryTree = new qtype_cppexpression_create_tree('i * j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(2, 3) == 6);
	}


	public function test_div(){
		$binaryTree = new qtype_cppexpression_create_tree('i / j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(4, 2) == 2);
	}


	public function test_percent(){
		$binaryTree = new qtype_cppexpression_create_tree('i % j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(5, 3) == 2);
	}


	public function test_greater_1(){
		$binaryTree = new qtype_cppexpression_create_tree('i > j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(2, 3) == 0);
	}

	public function test_greater_2(){
		$binaryTree = new qtype_cppexpression_create_tree('i > j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(3, 3) == 0);
	}

	public function test_greater_3(){
		$binaryTree = new qtype_cppexpression_create_tree('i > j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(4, 3) == 1);
	}


	public function test_less_1(){
		$binaryTree = new qtype_cppexpression_create_tree('i < j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(2, 3) == 1);
	}

	public function test_less_2(){
		$binaryTree = new qtype_cppexpression_create_tree('i < j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(3, 3) == 0);
	}

	public function test_less_3(){
		$binaryTree = new qtype_cppexpression_create_tree('i < j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(4, 3) == 0);
	}


	public function test_greater_or_equal_1(){
		$binaryTree = new qtype_cppexpression_create_tree('i >= j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(2, 3) == 0);
	}


	public function test_greater_or_equal_2(){
		$binaryTree = new qtype_cppexpression_create_tree('i >= j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(3, 3) == 1);
	}

	public function test_greater_or_equal_3(){
		$binaryTree = new qtype_cppexpression_create_tree('i >= j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(4, 3) == 1);
	}


	public function test_less_or_equal_1(){
		$binaryTree = new qtype_cppexpression_create_tree('i <= j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(2, 3) == 1);
	}

	public function test_less_or_equal_2(){
		$binaryTree = new qtype_cppexpression_create_tree('i <= j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(3, 3) == 1);
	}

	public function test_less_or_equal_3(){
		$binaryTree = new qtype_cppexpression_create_tree('i <= j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(4, 3) == 0);
	}


	public function test_equal_1(){
		$binaryTree = new qtype_cppexpression_create_tree('i == j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(2, 3) == 0);
	}


	public function test_equal_2(){
		$binaryTree = new qtype_cppexpression_create_tree('i == j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(3, 3) == 1);
	}


	public function test_equal_3(){
		$binaryTree = new qtype_cppexpression_create_tree('i == j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(4, 3) == 0);
	}


	public function test_different_1(){
		$binaryTree = new qtype_cppexpression_create_tree('i != j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(2, 3) == 1);
	}


	public function test_different_2(){
		$binaryTree = new qtype_cppexpression_create_tree('i != j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(3, 3) == 0);
	}


	public function test_different_3(){
		$binaryTree = new qtype_cppexpression_create_tree('i != j');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(4, 3) == 1);
	}


	public function test_and_1(){
		$binaryTree = new qtype_cppexpression_create_tree('i && 0');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(1, 0) == 0);
	}

	public function test_and_2(){
		$binaryTree = new qtype_cppexpression_create_tree('i && 0');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 0);
	}


	public function test_and_3(){
		$binaryTree = new qtype_cppexpression_create_tree('i && 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(1, 0) == 1);
	}


	public function test_and_4(){
		$binaryTree = new qtype_cppexpression_create_tree('i && 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 0);
	}


	public function test_or_1(){
		$binaryTree = new qtype_cppexpression_create_tree('i || 0');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(1, 0) == 1);
	}

	public function test_or_2(){
		$binaryTree = new qtype_cppexpression_create_tree('i || 0');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 0);
	}

	public function test_or_3(){
		$binaryTree = new qtype_cppexpression_create_tree('i || 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 1);
	}

	public function test_or_4(){
		$binaryTree = new qtype_cppexpression_create_tree('i || 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(1, 0) == 1);
	}


	public function test_not_1(){
		$binaryTree = new qtype_cppexpression_create_tree('! i');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(1, 0) == 0);
	}

	public function test_not_2(){
		$binaryTree = new qtype_cppexpression_create_tree('! i');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 1);
	}


	/*public function test_or_bit_1(){
		$binaryTree = new qtype_cppexpression_create_tree('i | 0');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(1, 0) == 1);
	}

	public function test_or_bit_2(){
		$binaryTree = new qtype_cppexpression_create_tree('i | 0');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 0);
	}

	public function test_or_bit_3(){
		$binaryTree = new qtype_cppexpression_create_tree('i | 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 1);
	}

	public function test_or_bit_4(){
		$binaryTree = new qtype_cppexpression_create_tree('i | 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(1, 0) == 1);
	}

	public function test_and_bit_1(){
		$binaryTree = new qtype_cppexpression_create_tree('i & 0');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(1, 0) == 0);
	}

	public function test_and_bit_2(){
		$binaryTree = new qtype_cppexpression_create_tree('i & 0');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 0);
	}


	public function test_and_bit_3(){
		$binaryTree = new qtype_cppexpression_create_tree('i & 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(1, 0) == 1);
	}


	public function test_and_bit_4(){
		$binaryTree = new qtype_cppexpression_create_tree('i & 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 0);
	}*/


	public function test_not_bit_1(){
		$binaryTree = new qtype_cppexpression_create_tree('~i');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == -1);
	}


	public function test_not_bit_2(){
		$binaryTree = new qtype_cppexpression_create_tree('~i');
		$tree = $binaryTree->get_binary_tree();

		/*echo "\n\n\n" . ~1 . "\n\n\n";*/

		$this->assertTrue($tree->calculate_expression(1, 0) == -2);
	}


	public function test_xor_bit(){
		$binaryTree = new qtype_cppexpression_create_tree('i ^ 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 1);
	}


	public function test_leftShift(){
		$binaryTree = new qtype_cppexpression_create_tree('i << 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(3, 0) == 6);
	}


	public function test_rightShift(){
		$binaryTree = new qtype_cppexpression_create_tree('i >> 1');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(3, 0) == 1);
	}


	public function test_parameter(){
		$binaryTree = new qtype_cppexpression_create_tree('i');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(3, 0) == 3);
	}


	public function test_complex_expression_1(){
		$binaryTree = new qtype_cppexpression_create_tree('!(i + j) && (9 > (j - 3))');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(9, 11) == 0);
	}

	public function test_complex_expression_2(){
		$binaryTree = new qtype_cppexpression_create_tree('!(i + j) && (9 > (j - 3))');
		$tree = $binaryTree->get_binary_tree();

		$this->assertTrue($tree->calculate_expression(0, 0) == 1);
	}
}	

?>